package cn.stylefeng.guns.modular.demo.service;

import cn.hutool.core.util.RandomUtil;
import cn.stylefeng.guns.dao.*;
import cn.stylefeng.guns.dao.entity.*;
import cn.stylefeng.guns.dao.entity.neww.PwkCg;
import cn.stylefeng.guns.dao.entity.neww.PwkMdXs;
import cn.stylefeng.guns.dao.entity.neww.PwkXs;
import cn.stylefeng.guns.dao.entity.yaode.*;
import cn.stylefeng.guns.dao.mapper.GaiaSdSalePayMsgMapper;
import cn.stylefeng.guns.dao.mapper.GaiaWmsDiaoboMMapper;
import cn.stylefeng.guns.dao.mapper.yaode.GaiaSdSaleDMapper;
import cn.stylefeng.guns.dao.mapper.yaode.GaiaSupplierBusinessMapper;
import cn.stylefeng.guns.dao.service.*;
import cn.stylefeng.guns.dao.service.neww.IPwkCgService;
import cn.stylefeng.guns.dao.service.neww.IPwkMdXsService;
import cn.stylefeng.guns.dao.service.neww.IPwkXsService;
import cn.stylefeng.guns.modular.demo.enums.SaleStockTypeEnum;
import cn.stylefeng.guns.util.RebateDateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Stopwatch;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Lists;
import com.google.common.collect.Table;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.Odd;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SyncService {
    @Resource
    private IGaiaProductBusinessService gaiaProductBusinessService;
    @Resource
    private GaiaSupplierBusinessMapper gaiaSupplierBusinessMapper;
    @Resource
    private IGoodsService goodsService;
    @Resource
    private ISupplierService supplierService;
    @Resource
    private DynamicDataSourceProperties dynamicDataSourceProperties;
    @Resource
    private GaiaSdSaleDMapper gaiaSdSaleDMapper;
    @Resource
    private GaiaSdSalePayMsgMapper gaiaSdSalePayMsgMapper;
    @Resource
    private ISaleStockService saleStockService;
    @Resource
    private IGaiaBatchInfoService gaiaBatchInfoService;
    @Resource
    private IStoreService storeService;
    @Resource
    private GaiaWmsDiaoboMMapper gaiaWmsDiaoboMMapper;
    @Resource
    private TestBizService testBizService;
    @Resource
    private IGaiaWmsTuigongMService gaiaWmsTuigongMService;
    @Resource
    private IGaiaWmsRkshMService gaiaWmsRkshMService;
    @Resource
    private IWholesaleSalesRecordService wholesaleSalesRecordService;
    @Resource
    private IGaiaSdIncomeStatementDService gaiaSdIncomeStatementDService;
    @Resource
    private IGaiaMaterialDocService gaiaMaterialDocService;
    @Resource
    private ISalesStockBatchService salesStockBatchService;
    @Resource
    private IGaiaWmsStockHService gaiaWmsStockHService;
    @Resource
    private IGaiaSdStockBatchHService gaiaSdStockBatchHService;

    @Resource
    private IPwkCgService pwkCgService;
    @Resource
    private IPwkXsService pwkXsService;
    @Resource
    private IPwkMdXsService pwkMdXsService;


    private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("HH:mm");

    public static final DateTimeFormatter SIMPLE_DATE_FORMAT1 = DateTimeFormatter.ofPattern("yyyyMMdd");
    public static final DateTimeFormatter SIMPLE_DATE_FORMAT2 = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

    public static final DateTimeFormatter SIMPLE_DATE_FORMAT4 = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss");

    public void syncAmount111() {
        int size = 1000;
        int offset = 0;
        while (true) {
            List<SaleStock> list = saleStockService.list(Wrappers.<SaleStock>lambdaQuery()
//                    .isNull(SaleStock::getBatchNo)
//                            .eq(SaleStock::getTag, "w0crdxdq50ss")
                            .ge(SaleStock::getSaleTime, 1714492800000L)
                            .last("limit " + offset + "," + size)
            );
            if (CollectionUtils.isEmpty(list)) {
                return;
            }
            offset += size;
            List<String> collect = list.stream().map(SaleStock::getBatchNo).collect(Collectors.toList());
            Map<String, String> collect1 = gaiaBatchInfoService.list(Wrappers.<GaiaBatchInfo>lambdaQuery().in(GaiaBatchInfo::getBatBatch, collect)).stream()
                    .collect(Collectors.toMap(GaiaBatchInfo::getBatBatch, GaiaBatchInfo::getBatBatchNo));

            list.stream().forEach(r -> {
                r.setBatch(collect1.getOrDefault(r.getBatchNo(), ""));
            });
            saleStockService.updateBatchById(list);
        }
    }

    public void sysnc() {
        List<SalesStockBatch> list = salesStockBatchService.list(Wrappers.<SalesStockBatch>lambdaQuery().eq(SalesStockBatch::getTime, "2024-05-31"));
        list.stream().forEach(r -> {
            String batchNo = r.getBatchNo();
            GaiaBatchInfo one = gaiaBatchInfoService.getOne(Wrappers.<GaiaBatchInfo>lambdaQuery().eq(GaiaBatchInfo::getBatBatch, batchNo));
            String batSupplierCode = one.getBatSupplierCode();
            Supplier one1 = supplierService.getOne(Wrappers.<Supplier>lambdaQuery().eq(Supplier::getSupplierCode, batSupplierCode));
            r.setSupplierId(one1.getSupplierId());
        });
        salesStockBatchService.updateBatchById(list);

    }

    public void syncAmount(String time) {
        LocalTime locaTime = LocalTime.now();
        LocalTime localTimeStart = locaTime.withMinute(0).withSecond(0).withHour(0).withNano(0);
        LocalTime localTimeEnd = locaTime.withHour(23).withMinute(59).withSecond(59).withNano(999);
        LocalDate parse = LocalDate.parse(time, SIMPLE_DATE_FORMAT1);
        long start = LocalDateTime.of(parse, localTimeStart).toInstant(ZonedDateTime.now().getOffset()).toEpochMilli();
        long end = LocalDateTime.of(parse, localTimeEnd).toInstant(ZonedDateTime.now().getOffset()).toEpochMilli();
        Map<String, Goods> goodsMap = goodsService.list().stream().collect(Collectors.toMap(Goods::getGoodsId, Function.identity()));
        int pageNo = 1;
        int pageSize = 1000;
        while (true) {
            List<SaleStock> list = saleStockService.list(Wrappers
                    .<SaleStock>lambdaQuery()
                    .eq(SaleStock::getTest, 0)
                    .eq(SaleStock::getType, "sale")
                    .ge(SaleStock::getSaleTime, start)
                    .le(SaleStock::getSaleTime, end)
                    .last("limit " + (pageNo - 1) * pageSize + "," + pageSize)
            );
            pageNo++;
            if (CollectionUtils.isEmpty(list)) {
                break;
            }

            List<String> matIdList = list.stream().filter(r -> StringUtils.isNotEmpty(r.getMaterialDocId()) && Objects.nonNull(r.getSellAmountReceivable()))
                    .map(r -> r.getMaterialDocId()).collect(Collectors.toList());
            Map<String, List<GaiaMaterialDoc>> matMap = gaiaMaterialDocService.list(Wrappers.<GaiaMaterialDoc>lambdaQuery().in(GaiaMaterialDoc::getMatId, matIdList))
                    .stream().collect(Collectors.groupingBy(GaiaMaterialDoc::getMatId));


            list.stream().forEach(r -> {
                String materialDocId = r.getMaterialDocId();
                List<GaiaMaterialDoc> gaiaMaterialDocs = matMap.get(materialDocId);
                if (CollectionUtils.isEmpty(gaiaMaterialDocs)) {
                    return;
                }
                String poId = gaiaMaterialDocs.get(0).getMatPoId();
                Goods goods = goodsMap.get(r.getGoodsId());
                if (Objects.nonNull(goods)) {
                    LambdaQueryWrapper<GaiaSdSaleD> eq = Wrappers.<GaiaSdSaleD>lambdaQuery()
                            .eq(GaiaSdSaleD::getGssdBillNo, poId)
//                            .eq(GaiaSdSaleD::getGssdBatch, r.getBatchNo())
                            .eq(GaiaSdSaleD::getGssdProId, goods.getCommodityCode());
                    List<GaiaSdSaleD> gaiaSdSaleDS = gaiaSdSaleDMapper.selectList(eq);
                    if (CollectionUtils.isNotEmpty(gaiaSdSaleDS)) {
                        GaiaSdSaleD gaiaSdSaleD = gaiaSdSaleDS.get(0);
                        BigDecimal gssdPrc1 = gaiaSdSaleD.getGssdPrc1();
                        Integer num = r.getNum();
                        Integer gssdQty = gaiaSdSaleD.getGssdQty();
                        if (!Objects.equals(num, gssdQty)) {
                            log.error("同步数据出错,数量不一致，num={},gssdQty={}", num, gssdQty);
                        }
                        BigDecimal gssdAmt = gaiaSdSaleD.getGssdAmt();
                        r.setSellAmountReceivable(gssdPrc1.multiply(new BigDecimal(gssdQty)));
                        r.setSellPaidAmount(gssdAmt);
                    } else {
                        log.info("同步数据出错，没有找到对应的销售单据，saleStock={}", JSON.toJSONString(r));
                    }
                }
            });
            saleStockService.updateBatchById(list);
        }


    }

    /**
     * 10.1 之后数据同步
     *
     * @param time
     */
    public void syncNewMaterialData(String time, String tag) {
        //清掉当天的数据
        LocalTime locaTime = LocalTime.now();
        LocalTime localTimeStart = locaTime.withMinute(0).withSecond(0).withHour(0).withNano(0);
        LocalTime localTimeEnd = locaTime.withHour(23).withMinute(59).withSecond(59).withNano(999);
        LocalDate parse = LocalDate.parse(time, SIMPLE_DATE_FORMAT1);
        long start = LocalDateTime.of(parse, localTimeStart).toInstant(ZonedDateTime.now().getOffset()).toEpochMilli();
        long end = LocalDateTime.of(parse, localTimeEnd).toInstant(ZonedDateTime.now().getOffset()).toEpochMilli();
        //测试数据不能清除
        LambdaQueryWrapper<SaleStock> le = Wrappers.<SaleStock>lambdaQuery().
                eq(SaleStock::getTest, 0)

                .ge(SaleStock::getSaleTime, start)
                .le(SaleStock::getSaleTime, end);
        if (StringUtils.isNotBlank(tag)) {
            le.eq(SaleStock::getTag, tag);
        } else {
            le.and(r -> r.eq(SaleStock::getTag, "").or().isNull(SaleStock::getTag));
        }
        saleStockService.remove(le);

        //基础数据
        Map<String, Goods> goodsMap = goodsService.list().stream().collect(Collectors.toMap(Goods::getCommodityCode, Function.identity()));
        Map<String, Supplier> supplierMap = supplierService.list().stream().collect(Collectors.toMap(Supplier::getSupplierCode, Function.identity()));
        Map<String, Store> storeMap = storeService.list().stream().collect(Collectors.toMap(Store::getStoreCode, Function.identity()));
        //采购数据
        syncNewYaodeSupplierData(time, goodsMap, supplierMap, tag);
        //总部销售数据
        syncNewXSData(time, goodsMap, supplierMap, tag);
        //门店销售
        syncNewMDXSData(time, goodsMap, supplierMap, tag);
        //生成测试数据批发数据
//        syncTestData(time);
    }


    /**
     * 三期数据同步
     *
     * @param time
     */
    public void syncMaterialData(String time) {
        //清掉当天的数据
        LocalTime locaTime = LocalTime.now();
        LocalTime localTimeStart = locaTime.withMinute(0).withSecond(0).withHour(0).withNano(0);
        LocalTime localTimeEnd = locaTime.withHour(23).withMinute(59).withSecond(59).withNano(999);
        LocalDate parse = LocalDate.parse(time, SIMPLE_DATE_FORMAT1);
        long start = LocalDateTime.of(parse, localTimeStart).toInstant(ZonedDateTime.now().getOffset()).toEpochMilli();
        long end = LocalDateTime.of(parse, localTimeEnd).toInstant(ZonedDateTime.now().getOffset()).toEpochMilli();
        //测试数据不能清除
        saleStockService.remove(Wrappers.<SaleStock>lambdaQuery().
                eq(SaleStock::getTest, 0)
                .and(r -> r.eq(SaleStock::getTag, "").or().isNull(SaleStock::getTag))
                .ge(SaleStock::getSaleTime, start)
                .le(SaleStock::getSaleTime, end));
        //基础数据
        Map<String, Goods> goodsMap = goodsService.list().stream().collect(Collectors.toMap(Goods::getCommodityCode, Function.identity()));
        Map<String, Supplier> supplierMap = supplierService.list().stream().collect(Collectors.toMap(Supplier::getSupplierCode, Function.identity()));
        Map<String, Store> storeMap = storeService.list().stream().collect(Collectors.toMap(Store::getStoreCode, Function.identity()));
        //同步数据
        syncNewData(time, goodsMap, supplierMap);
        //生成测试数据批发数据
//        syncTestData(time);
    }

    //更改为新数据源 10.1之后更新为新数据源  采购数据
    private void syncNewYaodeSupplierData(String time, Map<String, Goods> goodsMap, Map<String, Supplier> supplierMap, String tag) {
        log.info("开始同步采购数据time={}", time);
        LocalTime locaTime = LocalTime.now();
        LocalTime localTimeStart = locaTime.withMinute(0).withSecond(0).withHour(0).withNano(0);
        LocalTime localTimeEnd = locaTime.withHour(23).withMinute(59).withSecond(59).withNano(999);
        LocalDate parse = LocalDate.parse(time, SIMPLE_DATE_FORMAT1);
        long start = LocalDateTime.of(parse, localTimeStart).toInstant(ZonedDateTime.now().getOffset()).toEpochMilli();
        long end = LocalDateTime.of(parse, localTimeEnd).toInstant(ZonedDateTime.now().getOffset()).toEpochMilli();


        List<PwkCg> cgList = pwkCgService.list(Wrappers.<PwkCg>lambdaQuery()
                .ge(PwkCg::get时间, new Date(start)).le(PwkCg::get时间, new Date(end))
                .eq(PwkCg::get配送中心代码, "100")
        );
        if (CollectionUtils.isEmpty(cgList)) {
            log.error("没有采购数据time={}", time);
            return;
        }
        List<SaleStock> cgSaleStockList = cgList.stream().map(r -> {
            SaleStock saleStock = new SaleStock();
            Double 数量 = r.get数量();
            if (数量 >= 0) {
                saleStock.setSaleType(1);
            } else {
                saleStock.setSaleType(2);
            }
            saleStock.setType(SaleStockTypeEnum.CD.getType());
            String 产品代码 = r.get产品代码();
            Goods goods = goodsMap.get(产品代码);
            saleStock.setGoodsId(goods.getGoodsId());
            String 销售方代码 = r.get销售方代码();
            Supplier supplier = supplierMap.get(销售方代码);
            saleStock.setSupplierId(supplier.getSupplierId());

            saleStock.setNum(Math.abs(数量.intValue()));
            saleStock.setPrice(r.get单价());
            saleStock.setAmountReceivable(new BigDecimal(r.get金额()).abs());
            saleStock.setBatchNo(r.get批号());
            saleStock.setBatch(r.get批次号());
            saleStock.setFactoryName(r.get生产厂家());
            saleStock.setSaleTime(start);
            saleStock.setBillNo(r.get供应商出库单号());
            saleStock.setTest(0);
            saleStock.setCanRebate(1);
            if (Objects.nonNull(r.get采购价()) && Objects.nonNull(r.get采购税())) {
                BigDecimal 采购税 = r.get采购税();
                BigDecimal 采购价 = r.get采购价();
                BigDecimal add = 采购税.add(采购价);
                saleStock.setAmountReceivable(add);
                saleStock.setReceivablePrice(add.doubleValue());
            }

            if (StringUtils.isNotBlank(tag)) {
                saleStock.setTag(tag);
            }
            return saleStock;
        }).collect(Collectors.toList());
        log.info("采购数据同步完成time={},count={}", time, cgSaleStockList.size());
        saleStockService.saveBatch(cgSaleStockList);
    }

    /**
     * 总部销售
     *
     * @param time
     * @param goodsMap
     * @param supplierMap
     */
    private void syncNewXSData(String time, Map<String, Goods> goodsMap, Map<String, Supplier> supplierMap, String tag) {
        log.info("开始同步总部销售数据time={}", time);
        LambdaQueryWrapper<PwkXs> queryWrapper = Wrappers.<PwkXs>lambdaQuery()
                .eq(PwkXs::get日期, time)
                .notIn(PwkXs::get数据类型, Lists.newArrayList("批发销售订单", "批发销售退库订单号", "批发销退"))
                .eq(PwkXs::get配送中心代码, "100");
        List<PwkXs> list = pwkXsService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            log.error("没有总部销售数据time={}", time);
            return;
        }

        List<SaleStock> collect = list.stream().map(r -> {
            SaleStock saleStock = new SaleStock();
            Double 数量 = r.get数量();
            if (数量 >= 0) {
                saleStock.setSaleType(2);
            } else {
                saleStock.setSaleType(1);
            }
            saleStock.setNum(Math.abs(数量.intValue()));
            saleStock.setType(SaleStockTypeEnum.PD.getType());
            String 产品代码 = r.get产品代码();
            Goods goods = goodsMap.get(产品代码);
            saleStock.setGoodsId(goods.getGoodsId());
            String 供应商代码 = r.get供应商代码();
            Supplier supplier = supplierMap.get(供应商代码);
            if (Objects.nonNull(supplier)) {
                saleStock.setSupplierId(supplier.getSupplierId());
            }
            saleStock.setStoCode(r.get门店编码());
            saleStock.setStoName(r.get门店名称());


            saleStock.setPrice(r.get单价());
            saleStock.setAmountReceivable(r.get金额().abs());
            saleStock.setBatchNo(r.get批号());
            saleStock.setBatch(r.get预留1());
            saleStock.setFactoryName(r.get生产厂家());
            saleStock.setSaleTime(r.get时间().getTime());
            saleStock.setBillNo(r.get发货单号());
            saleStock.setGssdBillNo(r.get订单编号());
            saleStock.setTest(0);
            BigDecimal 配送价 = r.get配送价();
            BigDecimal 配送税 = r.get配送税();
            if (Objects.nonNull(配送价) && Objects.nonNull(配送税)) {
                BigDecimal add = 配送价.add(配送税);
                saleStock.setAmountReceivable(add);
                saleStock.setReceivablePrice(add.doubleValue());
            }
            if (StringUtils.isNotBlank(tag)) {
                saleStock.setTag(tag);
            }
            return saleStock;
        }).collect(Collectors.toList());
        log.info("总部销售数据同步完成time={},count={}", time, collect.size());
        saleStockService.saveBatch(collect);
    }


    /**
     * 门店销售
     *
     * @param time
     * @param goodsMap
     * @param supplierMap
     */
    private void syncNewMDXSData(String time, Map<String, Goods> goodsMap, Map<String, Supplier> supplierMap, String tag) {
        log.info("开始同步门店销售数据time={}", time);

        LocalTime locaTime = LocalTime.now();
        LocalTime localTimeStart = locaTime.withMinute(0).withSecond(0).withHour(0).withNano(0);
        LocalTime localTimeEnd = locaTime.withHour(23).withMinute(59).withSecond(59).withNano(999);
        LocalDate parse = LocalDate.parse(time, SIMPLE_DATE_FORMAT1);
        long start = LocalDateTime.of(parse, localTimeStart).toInstant(ZonedDateTime.now().getOffset()).toEpochMilli();
        long end = LocalDateTime.of(parse, localTimeEnd).toInstant(ZonedDateTime.now().getOffset()).toEpochMilli();


        LambdaQueryWrapper<PwkMdXs> queryWrapper = Wrappers.<PwkMdXs>lambdaQuery()
                .ge(PwkMdXs::get销售时间, new Date(start)).le(PwkMdXs::get销售时间, new Date(end))
                ;
        List<PwkMdXs> list = pwkMdXsService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            log.error("没有门店销售数据time={}", time);
            return;
        }
        List<SaleStock> collect = list.stream().map(r -> {
            SaleStock saleStock = new SaleStock();
            Double 数量 = r.get销售数量();
            if (数量 >= 0) {
                saleStock.setSaleType(1);
            } else {
                saleStock.setSaleType(2);
            }
            saleStock.setNum(Math.abs(数量.intValue()));
            saleStock.setType(SaleStockTypeEnum.LT.getType());
            String 产品代码 = r.get商品code();
            Goods goods = goodsMap.get(产品代码);
            saleStock.setGoodsId(goods.getGoodsId());
            String 采购方代码 = r.get供应商编码();
            Supplier supplier = supplierMap.get(采购方代码);
            if (Objects.nonNull(supplier)) {
                saleStock.setSupplierId(supplier.getSupplierId());
            }
            saleStock.setStoCode(r.get门店code());
            saleStock.setStoName(r.get门店名称());

            saleStock.setPrice(r.get零售价());
            saleStock.setAmountReceivable(r.get应收金额().abs());
            saleStock.setBatchNo(r.get批号());
            saleStock.setBatch(r.get批次号());
            saleStock.setFactoryName(r.get厂商());
            saleStock.setSaleTime(r.get销售时间().getTime());
            saleStock.setBillNo(r.get订单号());
            saleStock.setGssdBillNo(r.get订单号());
            saleStock.setAmountReceivable(r.get应收金额());
            saleStock.setReceivablePrice(r.get实收金额().doubleValue());
            saleStock.setCashier(r.get收银员());
            saleStock.setProductionEnterprise(r.get商品生产企业());
            saleStock.setSellPaidAmount(r.get实收金额());
            saleStock.setSelfCode(r.get商品code());
            saleStock.setTest(0);
            saleStock.setTime(r.get销售时间().getTime());
            saleStock.setSaleTime(r.get销售时间().getTime());
            saleStock.setSalerName(r.get销售员());
            saleStock.setPayName(r.get支付方式());
            if (StringUtils.isNotBlank(tag)) {
                saleStock.setTag(tag);
            }
            return saleStock;
        }).collect(Collectors.toList());
        log.info("总部销售数据同步完成time={},count={}", time, collect.size());
        saleStockService.saveBatch(collect);
    }


//    private void syncNewData(String time, Map<String, Goods> goodsMap, Map<String, Supplier> supplierMap, Map<String, Store> storeMap) {
//        LambdaQueryWrapper<GaiaMaterialDoc> cd = Wrappers.<GaiaMaterialDoc>lambdaQuery().eq(GaiaMaterialDoc::getMatDocDate, time).eq(GaiaMaterialDoc::getClient, "10000504").notIn(GaiaMaterialDoc::getMatType, Lists.newArrayList("XD", "ED"));
//
//        IPage<GaiaMaterialDoc> page = new Page(1, 200);
//        page = gaiaMaterialDocService.page(page, cd);
//        long total = page.getTotal();
//        if (total == 0) {
//            log.info("没有数据time={}", time);
//            return;
//        }
//        log.info("进销存数据同步time={},count={}", time, page.getTotal());
//        while (true) {
//
//
//        }
//
//
//        for (int i = 1; i < 500 && CollectionUtils.isNotEmpty(page.getRecords()); ) {
//
//
////            // 处理数据
////            List<GaiaMaterialDoc> records = page.getRecords();
////            List<SaleStock> collect = records.stream().map(r -> {
////                String matType = r.getMatType();
////                SaleStockTypeEnum saleStockTypeEnum = SaleStockTypeEnum.getByYaodeType(matType);
////                if (Objects.isNull(saleStockTypeEnum)) {
////                    return null;
////                }
////
////                SaleStock saleStock = new SaleStock();
////                saleStock.setType(saleStockTypeEnum.getType());
////                //商品编码
////                String wmSpBm = r.getMatProCode();
////                //门店
////                String proSite = r.getMatSiteCode();
////                String wmCjrq = r.getMatDocDate();
////                String wmCjsj = "010000";
////                //批号
////                String wmPh = r.getMatBatch();
////                List<GaiaBatchInfo> gaiaBatchInfoList = gaiaBatchInfoService.list(Wrappers.<GaiaBatchInfo>lambdaQuery().eq(GaiaBatchInfo::getBatBatch, wmPh));
////                if (CollectionUtils.isNotEmpty(gaiaBatchInfoList)) {
////                    GaiaBatchInfo gaiaBatchInfo = gaiaBatchInfoList.get(0);
////                    Supplier supplier = supplierMap.get(gaiaBatchInfo.getBatSupplierCode());
////                    if (Objects.nonNull(supplier)) {
////                        saleStock.setSupplierId(supplier.getSupplierId());
////                    }
////                    saleStock.setBatchNo(gaiaBatchInfo.getBatBatch());
////                    String batFactoryName = gaiaBatchInfo.getBatFactoryName();
////                    if (StringUtils.isNotEmpty(batFactoryName)) {
////                        saleStock.setFactoryName(batFactoryName.trim());
////                    }
////                }
////
////                Goods goods = goodsMap.get(wmSpBm);
////                if (Objects.nonNull(goods)) {
////                    saleStock.setGoodsId(goods.getGoodsId());
////                    saleStock.setPrice(goods.getPrice());
////                }
////                LocalDateTime parse = LocalDateTime.parse(wmCjrq + wmCjsj, SIMPLE_DATE_FORMAT2);
////                saleStock.setSaleTime(parse.toInstant(ZonedDateTime.now().getOffset()).toEpochMilli());
////                saleStock.setSaleType(saleStockTypeEnum.getSaleType());
////                saleStock.setNum(r.getMatQty().intValue());
////                saleStock.setCanRebate(1);
////                saleStock.setTest(0);
////                //外键id
////                saleStock.setMaterialDocId(r.getMatId());
////                saleStock.setStoCode(r.getMatSiteCode());
////                //采购
////                if (Objects.equals(saleStockTypeEnum.getYaodeType(), SaleStockTypeEnum.CD.getYaodeType())) {
////                    Double matBatAmt = r.getMatBatAmt();
////                    Double matAddTax = r.getMatRateBat();
////                    if (Objects.nonNull(matBatAmt)) {
////                        BigDecimal add = new BigDecimal(matBatAmt.toString()).add(new BigDecimal(matAddTax.toString()));
////                        saleStock.setAmountReceivable(add);
////                        saleStock.setReceivablePrice(add.doubleValue());
////                    }
////                    //销售
////                } else if (Objects.equals(saleStockTypeEnum.getType(), SaleStockTypeEnum.LT.getType())) {
////                    Double matQty = r.getMatQty();
////                    String matDebitCredit = r.getMatDebitCredit();
////                    //退货
////                    if (!Objects.equals(matDebitCredit, "H")) {
////                        saleStock.setSaleType(2);
////                    } else {
////                        saleStock.setSaleType(1);
////                    }
////                    Double matAddAmt = r.getMatAddAmt();
////                    Double matAddTax = r.getMatAddTax();
////                    if (Objects.nonNull(matAddAmt)) {
////                        BigDecimal amountReceivable = new BigDecimal(matAddAmt.toString()).add(new BigDecimal(matAddTax.toString()));
////                        saleStock.setAmountReceivable(amountReceivable);
////                        saleStock.setReceivablePrice(amountReceivable.doubleValue());
////                    }
////                    saleStock.setNum(Math.abs(matQty.intValue()));
////                } else {
////                    Double matQty = r.getMatQty();
////                    saleStock.setSaleType(saleStockTypeEnum.getSaleType());
////                    saleStock.setType(saleStockTypeEnum.getType());
////                    saleStock.setNum(matQty.intValue());
////                }
////                return saleStock;
////            }).collect(Collectors.toList());
////            log.info("进销存单个执行 time={},第{}次,原始数据={},保存数据={}", time, i, records.size(), collect.size());
////            saleStockService.saveBatch(collect);
////            page.setCurrent(++i);
////            page = gaiaMaterialDocService.page(page, cd);
////            log.info("进销存单个执行 time={},第{}次", time, i);
//        }
//
//    }

    private void syncNewData(String time, Map<String, Goods> goodsMap, Map<String, Supplier> supplierMap) {
        LambdaQueryWrapper<GaiaMaterialDoc> cd = Wrappers.<GaiaMaterialDoc>lambdaQuery().eq(GaiaMaterialDoc::getMatDocDate, time).eq(GaiaMaterialDoc::getClient, "10000504")
//                .eq(GaiaMaterialDoc::getMatType, "SY")
                .notIn(GaiaMaterialDoc::getMatType, Lists.newArrayList("XD", "ED"));


        int pageNo = 1;
        while (true) {
            IPage<GaiaMaterialDoc> page = new Page<>(pageNo, 20000);
            page = gaiaMaterialDocService.page(page, cd);
            log.info("进销存单个执行 time={},第{}次", time, pageNo);
            long total = page.getTotal();
            if (total == 0) {
                log.info("没有数据time={}", time);
                break;
            }
            log.info("进销存数据同步time={},count={}", time, page.getTotal());
            if (CollectionUtils.isEmpty(page.getRecords())) {
                break;
            }
            pageNo = pageNo + 1;

            // 处理数据
            List<GaiaMaterialDoc> records = page.getRecords();
            // 对元素进行分组并计数
            Map<String, Long> map = records.stream().collect(Collectors.groupingBy(GaiaMaterialDoc::getMatType, Collectors.counting()));
            log.info("分组计数 collect1 ={}", JSON.toJSONString(map));

//            List<String> phList = records.stream().map(GaiaMaterialDoc::getMatBatch).collect(Collectors.toList());
//            Map<String, GaiaBatchInfo> phMap = gaiaBatchInfoService.list(Wrappers.<GaiaBatchInfo>lambdaQuery().in(GaiaBatchInfo::getBatBatch, phList)).stream().collect(Collectors.toMap(GaiaBatchInfo::getBatBatch, Function.identity()));

            List<SaleStock> collect = records.stream().map(r -> {
                String matType = r.getMatType();
                SaleStockTypeEnum saleStockTypeEnum = SaleStockTypeEnum.getByYaodeType(matType);
                if (Objects.isNull(saleStockTypeEnum)) {
                    return null;
                }

                SaleStock saleStock = new SaleStock();
                saleStock.setType(saleStockTypeEnum.getType());
                //商品编码
                String wmSpBm = r.getMatProCode();
                //门店
                String proSite = r.getMatSiteCode();
                String wmCjrq = r.getMatDocDate();
                String wmCjsj = "010000";
                //批号
                String wmPh = r.getMatBatch();
                List<GaiaBatchInfo> list = gaiaBatchInfoService.list(Wrappers.<GaiaBatchInfo>lambdaQuery().eq(GaiaBatchInfo::getBatBatch, wmPh));
//                GaiaBatchInfo gaiaBatchInfo = phMap.get(wmPh);

                if (CollectionUtils.isNotEmpty(list)) {
                    GaiaBatchInfo gaiaBatchInfo = list.get(0);
                    Supplier supplier = supplierMap.get(gaiaBatchInfo.getBatSupplierCode());
                    if (Objects.nonNull(supplier)) {
                        saleStock.setSupplierId(supplier.getSupplierId());
                    }
                    saleStock.setBatchNo(gaiaBatchInfo.getBatBatch());
                    saleStock.setBatch(gaiaBatchInfo.getBatBatchNo());
                    String batFactoryName = gaiaBatchInfo.getBatFactoryName();
                    if (StringUtils.isNotEmpty(batFactoryName)) {
                        saleStock.setFactoryName(batFactoryName.trim());
                    }
                } else {
                    log.error("[批次数据异常] wmPh={}", wmPh);
                }

                Goods goods = goodsMap.get(wmSpBm);
                if (Objects.nonNull(goods)) {
                    saleStock.setGoodsId(goods.getGoodsId());
                    saleStock.setPrice(goods.getPrice());
                }
                LocalDateTime parse = LocalDateTime.parse(wmCjrq + wmCjsj, SIMPLE_DATE_FORMAT2);
                saleStock.setSaleTime(parse.toInstant(ZonedDateTime.now().getOffset()).toEpochMilli());
                saleStock.setSaleType(saleStockTypeEnum.getSaleType());
                Double matQty = r.getMatQty();
                saleStock.setNum(Objects.isNull(matQty) ? 0 : matQty.intValue());
                saleStock.setCanRebate(1);
                saleStock.setTest(0);
                //外键id
                saleStock.setMaterialDocId(r.getMatId());
                saleStock.setStoCode(r.getMatSiteCode());
                saleStock.setBillNo(r.getMatDnId());
                //采购
                if (Objects.equals(saleStockTypeEnum.getYaodeType(), SaleStockTypeEnum.CD.getYaodeType())) {
                    Double matBatAmt = r.getMatBatAmt();
                    Double matAddTax = r.getMatRateBat();
                    if (Objects.nonNull(matBatAmt)) {
                        BigDecimal add = new BigDecimal(matBatAmt.toString()).add(new BigDecimal(matAddTax.toString()));
                        saleStock.setAmountReceivable(add);
                        saleStock.setReceivablePrice(add.doubleValue());
                    }
                    //退货
                } else if (Objects.equals(saleStockTypeEnum.getYaodeType(), SaleStockTypeEnum.GD.getYaodeType())) {
                    Double matBatAmt = r.getMatBatAmt();
                    Double matAddTax = r.getMatRateBat();
                    if (Objects.nonNull(matBatAmt)) {
                        BigDecimal add = new BigDecimal(matBatAmt.toString()).add(new BigDecimal(matAddTax.toString()));
                        saleStock.setAmountReceivable(add);
                        saleStock.setReceivablePrice(add.doubleValue());
                    }
                    //损益
                } else if (Objects.equals(saleStockTypeEnum.getType(), SaleStockTypeEnum.SY.getType())) {
                    String matDebitCredit = r.getMatDebitCredit();
                    //退货
                    if (!Objects.equals(matDebitCredit, "H")) {
                        saleStock.setSaleType(2);
                    } else {
                        saleStock.setSaleType(1);
                    }
                    saleStock.setNum(Math.abs(matQty.intValue()));
                } else if (Objects.equals(saleStockTypeEnum.getType(), SaleStockTypeEnum.LS.getType())) {
                    String matDebitCredit = r.getMatDebitCredit();
                    //退货
                    if (!Objects.equals(matDebitCredit, "H")) {
                        saleStock.setSaleType(2);
                    } else {
                        saleStock.setSaleType(1);
                    }
                    saleStock.setNum(Math.abs(matQty.intValue()));

                    Double matBatAmt = r.getMatAddAmt();
                    Double matAddTax = r.getMatAddTax();
                    if (Objects.nonNull(matBatAmt)) {
                        BigDecimal add = new BigDecimal(matBatAmt.toString()).add(new BigDecimal(matAddTax.toString()));
                        saleStock.setAmountReceivable(add);
                        saleStock.setReceivablePrice(add.doubleValue());
                    }
                    String poId = r.getMatPoId();
                    LambdaQueryWrapper<GaiaSdSaleD> eq = Wrappers.<GaiaSdSaleD>lambdaQuery()
                            .eq(GaiaSdSaleD::getGssdBillNo, poId)
                            .eq(GaiaSdSaleD::getGssdBatch, r.getMatBatch())
                            .eq(GaiaSdSaleD::getGssdProId, r.getMatProCode());
                    List<GaiaSdSaleD> gaiaSdSaleDS = gaiaSdSaleDMapper.selectList(eq);
                    if (CollectionUtils.isNotEmpty(gaiaSdSaleDS)) {
                        GaiaSdSaleD gaiaSdSaleD = gaiaSdSaleDS.get(0);
                        BigDecimal gssdPrc1 = gaiaSdSaleD.getGssdPrc1();
                        Integer gssdQty = gaiaSdSaleD.getGssdQty();
                        BigDecimal gssdAmt = gaiaSdSaleD.getGssdAmt();
                        saleStock.setSellAmountReceivable(gssdPrc1.multiply(new BigDecimal(gssdQty)));
                        saleStock.setSellPaidAmount(gssdAmt);
                    } else {
                        log.info("同步数据出错，没有找到对应的销售单据，saleStock={}", JSON.toJSONString(r));
                    }
                } else {
                    saleStock.setSaleType(saleStockTypeEnum.getSaleType());
                    saleStock.setType(saleStockTypeEnum.getType());
                    saleStock.setNum(matQty.intValue());
                }

                log.info("进销存单个执行single 原始数据={}", JSON.toJSONString(r));
                log.info("进销存单个执行single 保存数据={}", JSON.toJSONString(saleStock));
                return saleStock;
            }).collect(Collectors.toList());
            // 对元素进行分组并计数
            Map<String, Long> collect1 = collect.stream().collect(Collectors.groupingBy(SaleStock::getType, Collectors.counting()));
            log.info("分组计数 collect1 ={}", JSON.toJSONString(collect1));
//            log.info("进销存单个执行 time={},第{}次,原始数据={},保存数据={}", time, pageNo, JSON.toJSONString(records), JSON.toJSONString(collect));
            saleStockService.saveBatch(collect);
        }
    }


    // 同步销售数据
// 同步发货退货数据
// 同步供应商进货退货数据
    public void syncData(String time) {
        //清掉当天的数据
        LocalTime locaTime = LocalTime.now();
        LocalTime localTimeStart = locaTime.withMinute(0).withSecond(0).withHour(0).withNano(0);
        LocalTime localTimeEnd = locaTime.withHour(23).withMinute(59).withSecond(59).withNano(999);
        LocalDate parse = LocalDate.parse(time, SIMPLE_DATE_FORMAT1);
        long start = LocalDateTime.of(parse, localTimeStart).toInstant(ZonedDateTime.now().getOffset()).toEpochMilli();
        long end = LocalDateTime.of(parse, localTimeEnd).toInstant(ZonedDateTime.now().getOffset()).toEpochMilli();
        //测试数据不能清除
        saleStockService.remove(Wrappers.<SaleStock>lambdaQuery().eq(SaleStock::getTest, 0).ge(SaleStock::getSaleTime, start).le(SaleStock::getSaleTime, end));
        //基础数据
        Map<String, Goods> goodsMap = goodsService.list().stream().collect(Collectors.toMap(Goods::getCommodityCode, Function.identity()));
        Map<String, Supplier> supplierMap = supplierService.list().stream().collect(Collectors.toMap(Supplier::getSupplierCode, Function.identity()));
        Map<String, Store> storeMap = storeService.list().stream().collect(Collectors.toMap(Store::getStoreCode, Function.identity()));
        //采购数据
//        syncBatchInfo(time, goodsMap, supplierMap, storeMap);
        syncRK(time, goodsMap, supplierMap);

        //供应商退货
        syncReturnSupplier(time, goodsMap, supplierMap, storeMap);
        //门店销售
        syncSaleStock(time, goodsMap, supplierMap, storeMap);

        //生成测试数据(采购)
        syncTestData(time);
    }


    // 同步销售数据
// 同步发货退货数据
// 同步供应商进货退货数据
    public void syncDataPurchase(String time) {
        //清掉当天的数据
        LocalTime locaTime = LocalTime.now();
        LocalTime localTimeStart = locaTime.withMinute(0).withSecond(0).withHour(0).withNano(0);
        LocalTime localTimeEnd = locaTime.withHour(23).withMinute(59).withSecond(59).withNano(999);
        LocalDate parse = LocalDate.parse(time, SIMPLE_DATE_FORMAT1);
        long start = LocalDateTime.of(parse, localTimeStart).toInstant(ZonedDateTime.now().getOffset()).toEpochMilli();
        long end = LocalDateTime.of(parse, localTimeEnd).toInstant(ZonedDateTime.now().getOffset()).toEpochMilli();
        //测试数据不能清除
        saleStockService.remove(Wrappers.<SaleStock>lambdaQuery().eq(SaleStock::getTest, 0).ge(SaleStock::getSaleTime, start).le(SaleStock::getSaleTime, end).eq(SaleStock::getType, "supplier"));
        //基础数据
        Map<String, Goods> goodsMap = goodsService.list().stream().collect(Collectors.toMap(Goods::getCommodityCode, Function.identity()));
        Map<String, Supplier> supplierMap = supplierService.list().stream().collect(Collectors.toMap(Supplier::getSupplierCode, Function.identity()));
        Map<String, Store> storeMap = storeService.list().stream().collect(Collectors.toMap(Store::getStoreCode, Function.identity()));
        //采购数据
//        syncBatchInfo(time, goodsMap, supplierMap, storeMap);
        syncRK(time, goodsMap, supplierMap);
        //供应商退货
        syncReturnSupplier(time, goodsMap, supplierMap, storeMap);
    }

    /**
     * 供应商退货
     *
     * @param time
     * @param goodsMap
     * @param supplierMap
     */
    private void syncGainsLosses(String time, Map<String, Goods> goodsMap, Map<String, Supplier> supplierMap, Map<String, Store> storeMap) {
//        List<GaiaSdIncomeStatementD> list = gaiaSdIncomeStatementDService.list(Wrappers.<GaiaSdIncomeStatementD>lambdaQuery().eq(GaiaSdIncomeStatementD::getGsisdDate, time));

        List<GaiaMaterialDoc> list = gaiaMaterialDocService.getSaleReturnList(time);
        log.info("{}供应商损益数据待同步数据一共{}", time, list.size());
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        List<SaleStock> collect = list.stream().map(r -> {
            String gsisdDate = r.getMatDocDate();
            //批次
            String gsisdBatch = r.getMatBatch();
            String gsisdProId = r.getMatProCode();
            Double matQty = r.getMatQty();
            //门店
            String gsisdBrId = r.getMatSiteCode();
            SaleStock saleStock = new SaleStock();
            saleStock.setType("loss");
            saleStock.setBatchNo(gsisdBatch);
            GaiaBatchInfo gaiaBatchInfo = gaiaBatchInfoService.getOne(Wrappers.<GaiaBatchInfo>lambdaQuery().eq(GaiaBatchInfo::getBatBatch, gsisdBatch));
            if (Objects.nonNull(gaiaBatchInfo)) {
                String batSupplierCode = gaiaBatchInfo.getBatSupplierCode();
                Supplier supplier = supplierMap.get(batSupplierCode);
                if (Objects.nonNull(supplier)) {
                    saleStock.setSupplierId(supplier.getSupplierId());
                }

                BigDecimal batPoPrice = gaiaBatchInfo.getBatPoPrice();
                if (Objects.nonNull(batPoPrice)) {
                    saleStock.setPrice(batPoPrice);
                }
                String batFactoryName = gaiaBatchInfo.getBatFactoryName();
                if (StringUtils.isNotEmpty(batFactoryName)) {
                    saleStock.setFactoryName(batFactoryName.trim());
                }
            }
            Goods goods = goodsMap.get(gsisdProId);
            if (Objects.nonNull(goods)) {
                saleStock.setGoodsId(goods.getGoodsId());
            }
            Store store = storeMap.get(gsisdBrId);
            if (Objects.nonNull(store)) {
                saleStock.setStoCode(store.getStoreCode());
                saleStock.setStoName(store.getStoreName());
            }
            LocalDateTime parse = LocalDateTime.of(LocalDate.parse(gsisdDate, SIMPLE_DATE_FORMAT1), LocalTime.now());
            saleStock.setSaleTime(parse.toInstant(ZonedDateTime.now().getOffset()).toEpochMilli());
            saleStock.setSaleType(2);
            saleStock.setNum(matQty.intValue());
            saleStock.setCanRebate(1);
            saleStock.setTest(0);
            return saleStock;
        }).collect(Collectors.toList());
        saleStockService.saveBatch(collect);
    }


    /**
     * 供应商退货
     *
     * @param time
     * @param goodsMap
     * @param supplierMap
     */
    private void syncReturnSupplier(String time, Map<String, Goods> goodsMap, Map<String, Supplier> supplierMap, Map<String, Store> storeMap) {
//        List<GaiaWmsTuigongM> list = gaiaWmsTuigongMService.list(Wrappers.<GaiaWmsTuigongM>lambdaQuery()
//                .eq(GaiaWmsTuigongM::getWmXgrq, time)
//                .in(GaiaWmsTuigongM::getProSite, Lists.newArrayList("100", "114"))
//
//        );
        List<GaiaMaterialDoc> list = gaiaMaterialDocService.getSaleReturnList(time);
        log.info("{}供应商退货数据待同步数据一共{}", time, list.size());
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        List<SaleStock> collect = list.stream().map(r -> {
            SaleStock saleStock = new SaleStock();
            saleStock.setType("supplier");
            saleStock.setBatchNo(r.getMatBatch());
            GaiaBatchInfo gaiaBatchInfo = gaiaBatchInfoService.getOne(Wrappers.<GaiaBatchInfo>lambdaQuery().eq(GaiaBatchInfo::getBatBatch, r.getMatBatch()));
            if (Objects.nonNull(gaiaBatchInfo)) {
                String batSupplierCode = gaiaBatchInfo.getBatSupplierCode();
                Supplier supplier = supplierMap.get(batSupplierCode);
                if (Objects.nonNull(supplier)) {
                    saleStock.setSupplierId(supplier.getSupplierId());
                }
                Goods goods = goodsMap.get(gaiaBatchInfo.getBatProCode());
                if (Objects.nonNull(goods)) {
                    saleStock.setGoodsId(goods.getGoodsId());
                }
                BigDecimal batPoPrice = gaiaBatchInfo.getBatPoPrice();
                if (Objects.nonNull(batPoPrice)) {
                    saleStock.setPrice(batPoPrice);
                }
                String batFactoryName = gaiaBatchInfo.getBatFactoryName();
                if (StringUtils.isNotEmpty(batFactoryName)) {
                    saleStock.setFactoryName(batFactoryName.trim());
                }
            }
            String wmXgrq = r.getMatDocDate();
            String wmXgsj = "080000";
            LocalDateTime parse = LocalDateTime.parse(wmXgrq + wmXgsj, SIMPLE_DATE_FORMAT2);
            saleStock.setSaleTime(parse.toInstant(ZonedDateTime.now().getOffset()).toEpochMilli());
            saleStock.setSaleType(2);
            saleStock.setNum(r.getMatQty().intValue());
            saleStock.setCanRebate(1);
            saleStock.setTest(0);
            return saleStock;
        }).collect(Collectors.toList());
        saleStockService.saveBatch(collect);
    }

    /**
     * 同步入库信息
     *
     * @param time
     * @param goodsMap
     * @param supplierMap
     */
    private void syncRK(String time, Map<String, Goods> goodsMap, Map<String, Supplier> supplierMap) {
//        List<GaiaWmsRkshM> list = gaiaWmsRkshMService.list(Wrappers.<GaiaWmsRkshM>lambdaQuery().eq(GaiaWmsRkshM::getWmCjrq, time).in(GaiaWmsRkshM::getProSite, Lists.newArrayList("100", "101", "114")));
        List<GaiaMaterialDoc> list = gaiaMaterialDocService.getPurchaseList(time);
        log.info("{}syncRK供应商批发数据待同步数据一共{}", time, list.size());
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        List<SaleStock> collect = list.stream().map(r -> {
            SaleStock saleStock = new SaleStock();
            saleStock.setType("supplier");
            //商品编码
            String wmSpBm = r.getMatProCode();
            //门店
            String proSite = r.getMatSiteCode();
            String wmCjrq = r.getMatDocDate();
            String wmCjsj = "080000";
            //批号
            String wmPh = r.getMatBatch();
            List<GaiaBatchInfo> gaiaBatchInfoList = gaiaBatchInfoService.list(Wrappers.<GaiaBatchInfo>lambdaQuery().eq(GaiaBatchInfo::getBatBatch, wmPh));
            if (CollectionUtils.isNotEmpty(gaiaBatchInfoList)) {
                GaiaBatchInfo gaiaBatchInfo = gaiaBatchInfoList.get(0);
                Supplier supplier = supplierMap.get(gaiaBatchInfo.getBatSupplierCode());
                if (Objects.nonNull(supplier)) {
                    saleStock.setSupplierId(supplier.getSupplierId());
                }
                saleStock.setBatchNo(gaiaBatchInfo.getBatBatch());
                String batFactoryName = gaiaBatchInfo.getBatFactoryName();
                if (StringUtils.isNotEmpty(batFactoryName)) {
                    saleStock.setFactoryName(batFactoryName.trim());
                }
            }

            Goods goods = goodsMap.get(wmSpBm);
            if (Objects.nonNull(goods)) {
                saleStock.setGoodsId(goods.getGoodsId());
                saleStock.setPrice(goods.getPrice());
            }
            LocalDateTime parse = LocalDateTime.parse(wmCjrq + wmCjsj, SIMPLE_DATE_FORMAT2);
            saleStock.setSaleTime(parse.toInstant(ZonedDateTime.now().getOffset()).toEpochMilli());
            saleStock.setSaleType(1);
            saleStock.setNum(r.getMatQty().intValue());

            saleStock.setCanRebate(1);
//            saleStock.setAmountReceivable()
            Double matBatAmt = r.getMatBatAmt();
            Double matAddTax = r.getMatRateBat();
            if (Objects.nonNull(matBatAmt)) {
                BigDecimal add = new BigDecimal(matBatAmt.toString()).add(new BigDecimal(matAddTax.toString()));
                saleStock.setAmountReceivable(add);
                saleStock.setReceivablePrice(add.doubleValue());
            }
            saleStock.setTest(0);

            return saleStock;
        }).collect(Collectors.toList());
        saleStockService.saveBatch(collect);
    }


    private Long getEndTime(String time) {
        LocalDate parse = LocalDate.parse(time, SIMPLE_DATE_FORMAT1);
        LocalDateTime localDateTime = LocalDateTime.of(parse, LocalTime.of(0, 0, 0));
        LocalDateTime endTime = localDateTime.plusDays(RandomUtil.randomInt(3, 4));
        LocalDateTime with = localDateTime.with(TemporalAdjusters.lastDayOfMonth());
        //大于月末的时间取月末
        if (endTime.isAfter(with)) {
            long epochMilli = with.toInstant(ZoneOffset.of("+8")).toEpochMilli();
            return epochMilli;
        } else {
            long epochMilli = endTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
            return epochMilli;
        }
    }

    public static void main(String[] args) {
        LocalDate dateTime1 = LocalDate.parse("20240831", RebateDateUtil.formatter);
        LocalDate now = LocalDate.now();
        int day = now.getDayOfYear() - dateTime1.getDayOfYear();
        //库存计算周期最后一天
        Long lastDayEnd = RebateDateUtil.getLastDayEnd(day);
        //库存计算周期最后一天开始
        Long lastDayBegin = RebateDateUtil.getLastDayBegin(day);
        //这个月第一天
        Long firstDayOfMonth = RebateDateUtil.getFirstDayOfMonth(lastDayBegin);

        LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastDayBegin), ZoneId.systemDefault());
        String month;
        String year;
        Boolean isCal = true;
        if (dateTime.equals(dateTime.with(TemporalAdjusters.lastDayOfMonth()))) {
            month = RebateDateUtil.formatMonth(firstDayOfMonth, 0);
            year = RebateDateUtil.formatYear(firstDayOfMonth);
            isCal = false;
        } else {
            month = RebateDateUtil.formatMonth(firstDayOfMonth);
            year = RebateDateUtil.formatYear(firstDayOfMonth);
        }
        System.out.println(month);
        System.out.println(year);
    }

    /**
     * 供应商进货
     *
     * @param time
     * @param goodsMap
     * @param supplierMap
     */
    private void syncBatchInfo(String time, Map<String, Goods> goodsMap, Map<String, Supplier> supplierMap, Map<String, Store> storeMap) {
        List<GaiaBatchInfo> list = gaiaBatchInfoService.list(Wrappers.<GaiaBatchInfo>lambdaQuery().eq(GaiaBatchInfo::getBatCreateDate, time));
        log.info("{}供应商批发数据待同步数据一共{}", time, list.size());
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        List<SaleStock> collect = list.stream().map(r -> {
            SaleStock saleStock = new SaleStock();
            saleStock.setType("supplier");
            saleStock.setBatchNo(r.getBatBatch());
            Supplier supplier = supplierMap.get(r.getBatSupplierCode());
            if (Objects.nonNull(supplier)) {
                saleStock.setSupplierId(supplier.getSupplierId());
            }
            Goods goods = goodsMap.get(r.getBatProCode());
            if (Objects.nonNull(goods)) {
                saleStock.setGoodsId(goods.getGoodsId());
            }
            Date lastUpdateTime = r.getLastUpdateTime();
            saleStock.setSaleTime(lastUpdateTime.getTime());
            saleStock.setSaleType(1);
            saleStock.setNum(r.getBatReceiveQty());
            saleStock.setBatchNo(r.getBatBatch());
            saleStock.setCanRebate(1);
            BigDecimal batPoPrice = r.getBatPoPrice();
            if (Objects.nonNull(batPoPrice)) {
                saleStock.setPrice(batPoPrice);
            }
            saleStock.setTest(0);
            String batFactoryName = r.getBatFactoryName();
            if (StringUtils.isNotEmpty(batFactoryName)) {
                saleStock.setFactoryName(batFactoryName.trim());
            }
            return saleStock;
        }).collect(Collectors.toList());
        saleStockService.saveBatch(collect);
    }

    /**
     * 生成测试数据
     *
     * @param time
     */
    public void syncTestData(String time) {
        Stopwatch stopwatch = Stopwatch.createStarted();
        log.info("[生成测试数据]开始生成数据，耗时={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        log.info("[generateTestData] time={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        calWholeSaleRecord(time, stopwatch, false);
//        //先计算退货
        testBizService.generateSingleTestDataReturn(time);
        log.info("[generateTestData] return time={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        log.info("[生成测试数据]退货完成，耗时={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        //再计算测试数据 发货
        testBizService.generateSingleTestData(time);
        log.info("[generateTestData] testdata time={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        log.info("[生成测试数据]测试数据生成完成，耗时={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        testBizService.generateSale(time);
        log.info("[generateTestData] sale time={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        log.info("[生成测试数据]生成销售数据，耗时={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        stopwatch.stop();
    }

    /**
     * 生成测试数据
     *
     * @param time
     */
    public void syncNewTestData(String time) {
        Stopwatch stopwatch = Stopwatch.createStarted();
        log.info("[生成测试数据]开始生成数据，耗时={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        log.info("[generateTestData] time={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        calWholeSaleRecord(time, stopwatch, true);
//        //先计算退货
//        testBizService.generateSingleTestDataReturn(time);
//        log.info("[generateTestData] return time={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
//        log.info("[生成测试数据]退货完成，耗时={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        //再计算测试数据 发货
        testBizService.generateSingleTestData(time);
        log.info("[generateTestData] testdata time={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        log.info("[生成测试数据]测试数据生成完成，耗时={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        testBizService.generateSale(time);
        log.info("[generateTestData] sale time={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        log.info("[生成测试数据]生成销售数据，耗时={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        stopwatch.stop();
    }

    /**
     * 先同步批发数据
     *
     * @param time
     * @param stopwatch
     * @return
     */
    private boolean calWholeSaleRecord(String time, Stopwatch stopwatch, Boolean isNew) {
        List<GaiaMaterialDoc> diboBoOriginals = null;
        if (isNew) {
            try {
                List<PwkXs> batchSaleList = pwkXsService.getBatchSaleList(time);
                diboBoOriginals = batchSaleList.stream().map(r -> {
                    GaiaMaterialDoc gaiaMaterialDoc = new GaiaMaterialDoc();
                    gaiaMaterialDoc.setMatBatch(r.get预留1());
                    gaiaMaterialDoc.setMatProCode(r.get产品代码());
                    gaiaMaterialDoc.setMatQty(r.get数量());
                    return gaiaMaterialDoc;
                }).collect(Collectors.toList());
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        } else {
            diboBoOriginals = gaiaMaterialDocService.getBatchSaleList(time);
        }
        log.info("{}批发销售数据 供应商测试数据待同步数据一共{}", time, diboBoOriginals.size());
        if (CollectionUtils.isEmpty(diboBoOriginals)) {
            return true;
        }

//        List<String> outIdList = diboBoOriginals.stream().map(DiboBoOriginal::getId).collect(Collectors.toList());
//        List<WholesaleSalesRecord> list = wholesaleSalesRecordService.list(Wrappers.<WholesaleSalesRecord>lambdaQuery()
//                .eq(WholesaleSalesRecord::getProCode, outIdList));

//        List<String> exitsIdList = list.stream().map(WholesaleSalesRecord::getOutId).collect(Collectors.toList());
        List<WholesaleSalesRecord> collect = diboBoOriginals.stream().filter(r -> r.getMatQty() != 0).map(r -> {
            String wmPch = r.getMatBatch();
            String wmSpBm = r.getMatProCode();
//            String matId = r.getMatPoId();
//            String matPoLineno = r.getMatPoLineno();
            String matType = r.getMatType();
//            String outId = matId + "|" + matPoLineno;
            List<WholesaleSalesRecord> list = wholesaleSalesRecordService.list(Wrappers.<WholesaleSalesRecord>lambdaQuery()
//                    .eq(WholesaleSalesRecord::getOutId, outId)
                    .eq(WholesaleSalesRecord::getBatchNo, wmPch).eq(WholesaleSalesRecord::getProCode, wmSpBm));

            if (CollectionUtils.isNotEmpty(list) && list.size() > 1) {
                log.error("同步数据失败，存在多条数据,list={}", JSON.toJSONString(list));
            }
            WholesaleSalesRecord wholesaleSalesRecord = list.stream().findFirst().orElse(null);
            Double matQty = r.getMatQty();
            int totalNum = matQty.intValue();
            //退货是-的


            if (Objects.nonNull(wholesaleSalesRecord)) {
                Integer oldTotalNum = wholesaleSalesRecord.getTotalNum();
                wholesaleSalesRecord.setTotalNum(totalNum);
                //数据有更新才要重新分配时间 保证老的分配完
                if (totalNum != oldTotalNum.intValue()) {
                    wholesaleSalesRecord.setEndTime(getEndTime(time));
                }
            } else {
                wholesaleSalesRecord = new WholesaleSalesRecord();
                wholesaleSalesRecord.setEndTime(getEndTime(time));
                wholesaleSalesRecord.setUsedNum(0);
                wholesaleSalesRecord.setProCode(wmSpBm);
                wholesaleSalesRecord.setBatchNo(r.getMatBatch());
                wholesaleSalesRecord.setTotalNum(totalNum);
            }
            return wholesaleSalesRecord;
        }).collect(Collectors.toList());
        log.info("[生成测试数据]开始插入，耗时={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        log.info("批发数据保存，collect={}", JSON.toJSONString(collect));
        wholesaleSalesRecordService.saveOrUpdateBatch(collect);
        log.info("[生成测试数据]插入完成，耗时={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        return false;
    }


    //同步销售数据 门店销售数据
    public void syncSaleStock(String time, Map<String, Goods> goodsMap, Map<String, Supplier> supplierMap, Map<String, Store> storeMap) {
//        List<GaiaSdSaleD> saleStockList = gaiaSdSaleDMapper.selectList(Wrappers.<GaiaSdSaleD>lambdaQuery()
//                .eq(GaiaSdSaleD::getGssdDate, time));

        List<GaiaMaterialDoc> saleStockList = gaiaMaterialDocService.getSaleList(time);
        log.info("{}待同步数据一共{}", time, saleStockList.size());

//        Map<String, Goods> goodsMap = goodsService.list().stream().collect(Collectors.toMap(Goods::getCommodityCode, Function.identity()));
//        Map<String, Supplier> supplierMap = supplierService.list().stream().collect(Collectors.toMap(Supplier::getSupplierCode, Function.identity()));

        List<SaleStock> collect = saleStockList.stream().map(r -> {
            String gssdBillNo = r.getMatPoId();
            String matPoLineno = r.getMatPoLineno();
            String gssdBrId = r.getMatSiteCode();
            String gssdProId = r.getMatProCode();
//            int val = Integer.parseInt(gssdSerial);
            List<GaiaSdSalePayMsg> gaiaSdSalePayMsgs = gaiaSdSalePayMsgMapper.selectList(Wrappers.<GaiaSdSalePayMsg>lambdaQuery().eq(GaiaSdSalePayMsg::getGsspmBillNo, r.getMatPoId()));
            SaleStock saleStock = new SaleStock();
            if (CollectionUtils.isNotEmpty(gaiaSdSalePayMsgs)) {
                if (gaiaSdSalePayMsgs.size() > 1) {
                    log.error("查到两条数据了gaiaSdSalePayMsgs ={}", JSON.toJSONString(gaiaSdSalePayMsgs));
                }
                GaiaSdSalePayMsg gaiaSdSalePayMsg = gaiaSdSalePayMsgs.get(0);
                saleStock.setGssdBillNo(gssdBillNo);
                saleStock.setPayName(gaiaSdSalePayMsg.getGsspmName());
            }
            List<GaiaSdSaleD> gaiaSdSaleDS = gaiaSdSaleDMapper.selectList(Wrappers.<GaiaSdSaleD>lambdaQuery().eq(GaiaSdSaleD::getGssdBillNo, gssdBillNo).eq(GaiaSdSaleD::getGssdSerial, gssdBillNo)

            );
            if (CollectionUtils.isNotEmpty(gaiaSdSaleDS)) {
                if (gaiaSdSaleDS.size() > 1) {
                    log.error("查到两条数据了gaiaSdSaleDS ={}", JSON.toJSONString(gaiaSdSaleDS));
                }
                GaiaSdSaleD gaiaSdSaleD = gaiaSdSaleDS.get(0);
                saleStock.setSalerId(gaiaSdSaleD.getGssdSalerId());
                saleStock.setCashier(gaiaSdSaleD.getGssdSalerId());
            }

//            saleStock.setGssdSerial(r.getGssdSerial());
            List<GaiaBatchInfo> list = gaiaBatchInfoService.list(Wrappers.<GaiaBatchInfo>lambdaQuery().eq(GaiaBatchInfo::getBatBatch, r.getMatBatch()));
            if (CollectionUtils.isNotEmpty(list)) {
                if (list.size() > 1) {
                    log.error("查到两条数据了GaiaBatchInfo ={}", JSON.toJSONString(list));
                }
                GaiaBatchInfo gaiaBatchInfo = list.get(0);
                String batSupplierCode = gaiaBatchInfo.getBatSupplierCode();
                Supplier supplier = supplierMap.get(batSupplierCode);
                if (Objects.nonNull(supplier)) {
                    saleStock.setSupplierId(supplier.getSupplierId());
                }

                BigDecimal batPoPrice = gaiaBatchInfo.getBatPoPrice();
                if (Objects.nonNull(batPoPrice)) {
                    saleStock.setPrice(batPoPrice);
                }
                String batFactoryName = gaiaBatchInfo.getBatFactoryName();
                if (StringUtils.isNotEmpty(batFactoryName)) {
                    saleStock.setFactoryName(batFactoryName.trim());
                }
                saleStock.setSalerName(gaiaBatchInfo.getBatSalesmanName());
                Store store = storeMap.get(gssdBrId);
                if (Objects.nonNull(store)) {
                    saleStock.setStoCode(store.getStoreCode());
                    saleStock.setStoName(store.getStoreName());
                }
                GaiaProductBusiness one = gaiaProductBusinessService.getOne(Wrappers.<GaiaProductBusiness>lambdaQuery().eq(GaiaProductBusiness::getProSelfCode, gaiaBatchInfo.getBatProCode()));
                if (Objects.nonNull(one)) {
                    saleStock.setProductionEnterprise(one.getProFactoryName());
                    saleStock.setHolder(one.getProHolder());
                }
            }

            Goods goods = goodsMap.get(gssdProId);
            if (Objects.nonNull(goods)) {
                saleStock.setGoodsId(goods.getGoodsId());
            }


//            Date lastUpdateTime = r.getLastUpdateTime();
            LocalDateTime parse = LocalDateTime.parse(r.getMatDocDate() + "080000", SIMPLE_DATE_FORMAT2);
            saleStock.setSaleTime(parse.toInstant(ZonedDateTime.now().getOffset()).toEpochMilli());
            saleStock.setSaleType(1);
            saleStock.setBillNo(r.getMatPoId());
//            saleStock.setNum(r.getGssdQty());
            saleStock.setBatchNo(r.getMatBatch());
            saleStock.setCanRebate(1);
            saleStock.setType("sale");

            Double matQty = r.getMatQty();
            String matDebitCredit = r.getMatDebitCredit();
            //退货
            if (!Objects.equals(matDebitCredit, "H")) {
                saleStock.setSaleType(2);
            } else {
                saleStock.setSaleType(1);
            }
            Double matAddAmt = r.getMatAddAmt();
            Double matAddTax = r.getMatAddTax();
            if (Objects.nonNull(matAddAmt)) {
                BigDecimal amountReceivable = new BigDecimal(matAddAmt.toString()).add(new BigDecimal(matAddTax.toString()));
//                BigDecimal amountReceivable = new BigDecimal(Math.abs(matAddAmt + matAddTax));
                saleStock.setAmountReceivable(amountReceivable);
                saleStock.setReceivablePrice(amountReceivable.doubleValue());
            }
            saleStock.setNum(Math.abs(matQty.intValue()));
//            saleStock.setBigClass(r.getbi);


//            saleStock.setMidClass();

//            saleStock.setProClass();
//            saleStock.setProCommonName();
//            saleStock.setProDepict();
//            saleStock.setProMedProductCode();
//            saleStock.setProSaleClass();
            saleStock.setTest(0);
//            saleStock.setStoName();
            saleStock.setStoCode(r.getMatSiteCode());


            return saleStock;
        }).collect(Collectors.toList());
        log.info("{}销售数据，保存数据一共{}", time, collect.size());
        saleStockService.saveBatch(collect);
    }


    public void syncStoreData() {
        // 同步门店数据
        List<StoreOriginal> storeList = gaiaSdSaleDMapper.getStoreList();
        List<Store> suppliers = storeList.stream().map(r -> {
            String stoCode = r.getStoCode();

            Store store = storeService.getOne(Wrappers.<Store>lambdaQuery().eq(Store::getStoreCode, stoCode));
            if (Objects.isNull(store)) {
                store = new Store();
                store.setStoreCode(stoCode);
                store.setStoreName(r.getStoName());
            }

            String gsstDailyCloseDate = r.getGsstDailyCloseDate();
            String gsstDailyOpenDate = r.getGsstDailyOpenDate();
            if (StringUtils.isNotBlank(gsstDailyCloseDate)) {
                try {
                    store.setCloseDate(SIMPLE_DATE_FORMAT.parse(gsstDailyCloseDate));
                } catch (ParseException e) {
                    log.warn("parse errorgsstDailyCloseDate ={}", gsstDailyCloseDate, e);
                }
            }
            if (StringUtils.isNotBlank(gsstDailyOpenDate)) {
                try {
                    store.setOpenDate(SIMPLE_DATE_FORMAT.parse(gsstDailyOpenDate));
                } catch (ParseException e) {
                    log.warn("parse errorgsstDailyOpenDate={}", gsstDailyOpenDate, e);
                }
            }
            return store;
        }).collect(Collectors.toList());
        storeService.saveOrUpdateBatch(suppliers);
    }


    public void syncData() {
        // 同步供应商
        List<GaiaSupplierBusiness> supplierBusinesses = gaiaSupplierBusinessMapper.selectList(Wrappers.lambdaQuery());
        List<Supplier> suppliers = supplierBusinesses.stream().map(r -> {
            String supSelfCode = r.getSupSelfCode();
            Supplier supplier = supplierService.getOne(Wrappers.<Supplier>lambdaQuery().eq(Supplier::getSupplierCode, supSelfCode));
            if (Objects.isNull(supplier)) {
                supplier = new Supplier();
                supplier.setSupplierCode(supSelfCode);
            }
            supplier.setName(r.getSupName());
            String supRegAdd = r.getSupRegAdd();
            supplier.setAddress(supRegAdd);
            supplier.setInProvince(supRegAdd.contains("浙江省") ? 1 : 0);
            return supplier;
        }).collect(Collectors.toList());
        supplierService.saveOrUpdateBatch(suppliers);
        //同步商品
        List<GaiaProductBusiness> gaiaProductBusinesses = gaiaProductBusinessService.list(Wrappers.lambdaQuery());
        List<Goods> goodsList = gaiaProductBusinesses.stream().map(r -> {
            String proSelfCode = r.getProSelfCode();
            Goods goods = goodsService.getOne(Wrappers.<Goods>lambdaQuery().eq(Goods::getCommodityCode, proSelfCode));
            if (Objects.isNull(goods)) {
                goods = new Goods();
                goods.setCommodityCode(proSelfCode);
            }
            goods.setVender(r.getProFactoryName());
            goods.setProPym(r.getProPym());
            goods.setCommodityName(r.getProName());
            goods.setCommodityUnit(r.getProUnit());
            goods.setCommoditySpec(r.getProSpecs());
            Double proHyj = r.getProHyj();
            if (Objects.nonNull(proHyj)) {
                goods.setPrice(BigDecimal.valueOf(proHyj));
            } else {
                goods.setPrice(new BigDecimal(0));
            }
            return goods;
        }).collect(Collectors.toList());
        goodsService.saveOrUpdateBatch(goodsList);
    }


    //从哪天算起
    public void calStock(int day) {


        Map<String, Goods> goodsMap = goodsService.list(Wrappers.lambdaQuery()).stream().collect(Collectors.toMap(Goods::getGoodsId, Function.identity()));
        //库存计算周期最后一天
        Long lastDayEnd = RebateDateUtil.getLastDayEnd(day);
        //库存计算周期最后一天开始
        Long lastDayBegin = RebateDateUtil.getLastDayBegin(day);
        //这个月第一天
        Long firstDayOfMonth = RebateDateUtil.getFirstDayOfMonth(lastDayBegin);

        LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastDayBegin), ZoneId.systemDefault());
        String month;
        String year;
        Boolean isCal = true;
        if (dateTime.equals(dateTime.with(TemporalAdjusters.lastDayOfMonth()))) {
            month = RebateDateUtil.formatMonth(firstDayOfMonth, 0);
            year = RebateDateUtil.formatYear(firstDayOfMonth);
            isCal = false;
        } else {
            month = RebateDateUtil.formatMonth(firstDayOfMonth);
            year = RebateDateUtil.formatYear(firstDayOfMonth);
        }

        String format1 = RebateDateUtil.format1(lastDayEnd);
//        //清掉当天的数据
        boolean remove = salesStockBatchService.remove(Wrappers.<SalesStockBatch>lambdaQuery()
                .eq(SalesStockBatch::getTime, format1)
//                .notIn(SalesStockBatch::getStoCode, "100")
        );

        String time = RebateDateUtil.format1(lastDayEnd);
        List<Store> list = storeService.list(Wrappers.<Store>lambdaQuery());

        Map<String, Supplier> supplierMap = supplierService.list(Wrappers.lambdaQuery())
                .stream().collect(Collectors.toMap(Supplier::getSupplierCode, Function.identity()));


        calChainStock(time, "100", month, year, firstDayOfMonth, lastDayEnd, goodsMap, supplierMap, isCal);


        //按门店计算库存
        for (Store store : list) {
            try {
                // batchno,pro_code num
                Table<String, String, SalesStockBatch> table = HashBasedTable.create();
                // 连锁库存
                List<GaiaSdStockBatchH> gaiaSdStockBatchHList = gaiaSdStockBatchHService.list(Wrappers.<GaiaSdStockBatchH>query()
                        .select("gssb_pro_id", "gssb_batch", "sum(gssb_qty) as gssb_qty")
                        .eq("gssb_br_id", store.getStoreCode())
                        .eq("mat_assess_month", month)
                        .eq("mat_assess_year", year)
                        .groupBy("gssb_pro_id", "gssb_batch"));
//                Set<String> batchList = gaiaSdStockBatchHList.stream().map(GaiaSdStockBatchH::getGssbBatch).collect(Collectors.toSet());
//                Map<String, GaiaBatchInfo> batchInfoMap = gaiaBatchInfoService.list(Wrappers.<GaiaBatchInfo>lambdaQuery().in(GaiaBatchInfo::getBatBatch, batchList)).stream().collect(Collectors.toMap(GaiaBatchInfo::getBatBatch, Function.identity()));

                gaiaSdStockBatchHList.forEach(r -> {
                    SalesStockBatch salesStockBatch = new SalesStockBatch();
                    Double gssbQty = r.getGssbQty();
                    salesStockBatch.setNum(Objects.isNull(gssbQty) ? 0 : gssbQty.intValue());
                    salesStockBatch.setProCode(r.getGssbProId());
                    salesStockBatch.setBatchNo(r.getGssbBatch());
                    salesStockBatch.setTestNum(0);
                    salesStockBatch.setTime(time);
                    salesStockBatch.setStoCode(store.getStoreCode());
                    table.put(r.getGssbBatch(), r.getGssbProId(), salesStockBatch);
                });

                if (isCal) {
                    QueryWrapper<SaleStock> queryWrapper = Wrappers.<SaleStock>query().select("goods_id,batch_no,type,sale_type,sum(num) as num");
                    queryWrapper.eq("sto_code", store.getStoreCode());
                    queryWrapper.eq("test", 0);

                    queryWrapper.between("sale_time", firstDayOfMonth, lastDayEnd)
                            .groupBy("goods_id,batch_no,type,sale_type")
                            .orderByAsc("goods_id");
                    List<SaleStock> saleStocks = saleStockService.list(queryWrapper);
                    saleStocks.stream().forEach(r -> {
                        if (Objects.isNull(r)) {
                            return;
                        }
                        if (Objects.isNull(r.getBatchNo())) {
                            return;
                        }
                        Goods goods = goodsMap.get(r.getGoodsId());
                        if (Objects.isNull(goods)) {
                            log.error("商品不存在goodsId={}", JSON.toJSONString(r));
                        } else {
                            SalesStockBatch salesStockBatch = table.get(r.getBatchNo(), goods.getCommodityCode());
                            if (Objects.isNull(salesStockBatch)) {
                                salesStockBatch = new SalesStockBatch();
                                salesStockBatch.setNum(0);
                                salesStockBatch.setProCode(goods.getCommodityCode());
                                salesStockBatch.setBatchNo(r.getBatchNo());
                                salesStockBatch.setTestNum(0);
                                salesStockBatch.setTime(time);
                                salesStockBatch.setStoCode(store.getStoreCode());
                            }
                            //计算门店
                            Integer amount = calStoreNum(r);
                            salesStockBatch.setNum(salesStockBatch.getNum() + amount);
                            table.put(r.getBatchNo(), goods.getCommodityCode(), salesStockBatch);
                        }

                    });
                }
                Collection<SalesStockBatch> values = table.values();
                List<SalesStockBatch> collect = values.stream().filter(r -> r.getTestNum() > 0 || r.getNum() > 0).collect(Collectors.toList());
                collect.forEach(r -> {
                    try {
                        r.setTime(format1);
                        String batchNo = r.getBatchNo();
                        GaiaBatchInfo gaiaBatchInfo = gaiaBatchInfoService.getOne(Wrappers.<GaiaBatchInfo>lambdaQuery().eq(GaiaBatchInfo::getBatBatch, batchNo));
                        if (Objects.nonNull(gaiaBatchInfo)) {
                            String batSupplierCode = gaiaBatchInfo.getBatSupplierCode();
                            Supplier supplier = supplierMap.get(batSupplierCode);
                            if (Objects.nonNull(supplier)) {
                                r.setSupplierId(supplier.getSupplierId());
                            }
                        }
                    } catch (Exception e) {
                        log.error("门店库存计算异常store={}", JSON.toJSONString(store), e);

                    }
                });

                if (CollectionUtils.isNotEmpty(collect)) {
                    salesStockBatchService.saveBatch(collect);
                }
            } catch (Exception e) {
                log.error("门店库存计算异常store={}", JSON.toJSONString(store));
                continue;
            }
        }
    }


    private void calChainStock(String time, String storeCode, String month, String year, Long firstDayOfMonth, Long lastDayEnd, Map<String, Goods> goodsMap, Map<String, Supplier> supplierMap, Boolean isCal) {
        // batchno,pro_code num
        Table<String, String, SalesStockBatch> table = HashBasedTable.create();
        //设置一些特殊数据
        init(table, time);

        // 连锁库存
        List<GaiaWmsStockH> gaiaWmsStockHList = gaiaWmsStockHService.list(Wrappers.<GaiaWmsStockH>query().select("pro_code", "batch", "sum(total_qty) as total_qty")
                .eq("pro_site", "100").eq("stock_month", month).eq("stock_year", year)
//                .eq("pro_code", "10101140012")
                .not(r -> r.eq("TOTAL_QTY ", 0)).groupBy("pro_code", "batch"));
        gaiaWmsStockHList.forEach(r -> {
            SalesStockBatch salesStockBatch = table.get(r.getBatch(), r.getProCode());
            if (Objects.isNull(salesStockBatch)) {
                salesStockBatch = new SalesStockBatch();
                salesStockBatch.setNum(r.getTotalQty().intValue());
                salesStockBatch.setProCode(r.getProCode());
                salesStockBatch.setBatchNo(r.getBatch());
                salesStockBatch.setTestNum(0);
                salesStockBatch.setStoCode(storeCode);
            } else {
                salesStockBatch.setNum(salesStockBatch.getNum() + r.getTotalQty().intValue());
            }
            table.put(r.getBatch(), r.getProCode(), salesStockBatch);
        });
        if (isCal) {
            //批发销售连锁库存
            List<WholesaleSalesRecord> wholesaleSalesRecordList = wholesaleSalesRecordService.list(Wrappers.<WholesaleSalesRecord>lambdaQuery()
//                .eq(WholesaleSalesRecord::getProCode, "10101140012")
            );
            wholesaleSalesRecordList.stream().forEach(r -> {
                SalesStockBatch salesStockBatch = table.get(r.getBatchNo(), r.getProCode());
                if (Objects.isNull(salesStockBatch)) {
                    salesStockBatch = new SalesStockBatch();
                    salesStockBatch.setNum(0);
                    salesStockBatch.setProCode(r.getProCode());
                    salesStockBatch.setBatchNo(r.getBatchNo());
                    salesStockBatch.setTestNum(0);
                    salesStockBatch.setTime(time);
                    salesStockBatch.setStoCode(storeCode);
                }
                salesStockBatch.setTestNum(salesStockBatch.getTestNum() + Optional.ofNullable(r).map(z -> z.getTotalNum() - z.getUsedNum()).orElse(0));
                table.put(r.getBatchNo(), r.getProCode(), salesStockBatch);
            });

            QueryWrapper<SaleStock> queryWrapper = Wrappers.<SaleStock>query().select("goods_id,batch_no,type,sale_type,sum(num) as num");
            queryWrapper.eq("sto_code", storeCode);
            queryWrapper.eq("test", 0);
//        queryWrapper.eq("goods_id", "1759426002687119365");

            queryWrapper.between("sale_time", firstDayOfMonth, lastDayEnd).groupBy("goods_id,batch_no,type,sale_type").orderByAsc("goods_id");
            List<SaleStock> saleStocks = saleStockService.list(queryWrapper);
            saleStocks.stream().forEach(r -> {
                Goods goods = goodsMap.get(r.getGoodsId());
                if (Objects.isNull(goods)) {
                    log.error("商品不存在goodsId={}", JSON.toJSONString(r));
                    return;
                }

                SalesStockBatch salesStockBatch = table.get(r.getBatchNo(), goods.getCommodityCode());
                if (Objects.isNull(salesStockBatch)) {
                    salesStockBatch = new SalesStockBatch();
                    salesStockBatch.setNum(0);
                    salesStockBatch.setProCode(goods.getCommodityCode());
                    salesStockBatch.setBatchNo(r.getBatchNo());
                    salesStockBatch.setTestNum(0);
                    salesStockBatch.setTime(time);
                    salesStockBatch.setStoCode(storeCode);
                }
                Integer amount = calChainNum(r);

                salesStockBatch.setNum(salesStockBatch.getNum() + amount);
                String batchNo = r.getBatchNo();
                String commodityCode = goods.getCommodityCode();
                if (Objects.nonNull(batchNo) && Objects.nonNull(commodityCode)) {
                    table.put(r.getBatchNo(), goods.getCommodityCode(), salesStockBatch);
                }
            });
            //减去批发销售的数量
            String startTime = RebateDateUtil.format(firstDayOfMonth);
            String endTime = RebateDateUtil.format(lastDayEnd);
            List<GaiaMaterialDoc> batchSaleList = gaiaMaterialDocService.getBatchSaleList(startTime, endTime);
            batchSaleList.stream().forEach(r -> {
                String matProCode = r.getMatProCode();
                String matBatch = r.getMatBatch();
                String matType = r.getMatType();
                Double matQty = r.getMatQty();

                SalesStockBatch salesStockBatch = table.get(matBatch, matProCode);
                if (Objects.isNull(salesStockBatch)) {
                    salesStockBatch = new SalesStockBatch();
                    salesStockBatch.setNum(0);
                    salesStockBatch.setProCode(matProCode);
                    salesStockBatch.setBatchNo(matBatch);
                    salesStockBatch.setTestNum(0);
                    salesStockBatch.setStoCode(storeCode);
                }
                if (Objects.equals(matType, SaleStockTypeEnum.XD.getYaodeType())) {
                    salesStockBatch.setNum(salesStockBatch.getNum() - matQty.intValue());
                } else {
                    salesStockBatch.setNum(salesStockBatch.getNum() + matQty.intValue());
                }
                table.put(matBatch, matProCode, salesStockBatch);
            });

        }
        String format1 = RebateDateUtil.format1(lastDayEnd);
        Collection<SalesStockBatch> values = table.values();
        values.stream().forEach(r -> {
            r.setTime(format1);
            String batchNo = r.getBatchNo();
            GaiaBatchInfo gaiaBatchInfo = gaiaBatchInfoService.getOne(Wrappers.<GaiaBatchInfo>lambdaQuery().eq(GaiaBatchInfo::getBatBatch, batchNo));
            if (Objects.nonNull(gaiaBatchInfo)) {
                String batSupplierCode = gaiaBatchInfo.getBatSupplierCode();
                Supplier supplier = supplierMap.get(batSupplierCode);
                if (Objects.nonNull(supplier)) {
                    r.setSupplierId(supplier.getSupplierId());
                }
            }
        });

        if (CollectionUtils.isNotEmpty(values)) {
            log.info("最终库存数据保存，values={}", values.size());
            salesStockBatchService.saveBatch(values);
        }
    }

    /**
     * 设置一些特殊数据
     *
     * @param table
     */
    private void init(Table<String, String, SalesStockBatch> table, String time) {
        initPut(5, "10102080240", "P20220002579", table, time);
        initPut(3, "10102080240", "P20220009438", table, time);
        initPut(15, "10202190047", "P20220000991", table, time);
        initPut(3, "10202190047", "P20220006814", table, time);
        initPut(59, "10202190330", "P20220006325", table, time);
        initPut(105, "10202190330", "P20220000986", table, time);
        initPut(207, "10202190330", "P20220008433", table, time);
        initPut(42, "10202190330", "P20220009503", table, time);
        initPut(23, "10202190573", "P20220000982", table, time);
        initPut(6, "10202190599", "P20220008798", table, time);
        initPut(9, "10202190599", "P20220003151", table, time);
        initPut(32, "10202191151", "P20220005910", table, time);
        initPut(3, "10202191151", "P20220000974", table, time);
        initPut(3, "10202191217", "P20220001826", table, time);
        initPut(5, "10202191151", "P20220007210", table, time);
        initPut(6, "10202191151", "P20220007211", table, time);
        initPut(9, "10202191217", "P20220006536", table, time);
        initPut(5, "10202191217", "P20220007961", table, time);
        initPut(20, "10202190573", "P20220007434", table, time);
        initPut(23, "10202190573", "P20220007883", table, time);
        initPut(3, "10202090241", "P20220003720", table, time);
        initPut(1, "10202090241", "P20220007536", table, time);
        initPut(21, "10102080240", "P20220004580", table, time);
        initPut(7, "10202190069", "P20220010551", table, time);
    }

    private void initPut(Integer num, String proCode, String batchNo, Table<String, String, SalesStockBatch> table, String time) {
        SalesStockBatch salesStockBatch3 = new SalesStockBatch();
        salesStockBatch3.setNum(-num);
        salesStockBatch3.setProCode(proCode);
        salesStockBatch3.setBatchNo(batchNo);
        salesStockBatch3.setTestNum(0);
        salesStockBatch3.setTime(time);
        salesStockBatch3.setStoCode("100");
        table.put(batchNo, proCode, salesStockBatch3);
    }

    private Integer calChainNum(SaleStock stock) {
        Integer saleType = stock.getSaleType();
        String type = stock.getType();
        Integer num = stock.getNum();
        if (saleType == 2 && "supplier".equals(type)) {
            return -num;
        } else if (saleType == 1 && "supplier".equals(type)) {
            return num;
        } else if (saleType == 1 && "store".equals(type)) {
            return num;
        } else if (saleType == 2 && "store".equals(type)) {
            return -num;
        } else if (saleType == 2 && "SY".equals(type)) {
            return num;
        } else if (saleType == 1 && "SY".equals(type)) {
            return -num;
        } else if ("BD".equals(type)) {
            return -num;
        } else {
            return 0; // default case if none of the conditions are met
        }
    }

    /**
     * when sale_type=2 and type ='sale' then num
     * when sale_type=1 and type ='sale' then -num
     * when sale_type=1 and type ='store' then num
     * when sale_type=2 and type ='store' then -num
     * when sale_type=2 and type ='SY' then num
     * when sale_type=1 and type ='SY' then -num
     * when  type ='BD' then -num
     *
     * @param stock
     * @return
     */
    private Integer calStoreNum(SaleStock stock) {
        Integer saleType = stock.getSaleType();
        String type = stock.getType();
        Integer num = stock.getNum();
        if (saleType == 2 && "sale".equals(type)) {
            return num;
        } else if (saleType == 1 && "sale".equals(type)) {
            return -num;
        } else if (saleType == 1 && "store".equals(type)) {
            return -num;
        } else if (saleType == 2 && "store".equals(type)) {
            return num;
        } else if (saleType == 2 && "SY".equals(type)) {
            return num;
        } else if (saleType == 1 && "SY".equals(type)) {
            return -num;
        } else if ("BD".equals(type)) {
            return -num;
        } else {
            return 0; // default case if none of the conditions are met
        }
    }

    /**
     * 生成测试数据
     *
     * @param time
     */
    public void syncTestDataV2(String time) {
        Stopwatch stopwatch = Stopwatch.createStarted();
        log.info("[生成测试数据]开始生成数据，耗时={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        List<GaiaMaterialDoc> diboBoOriginals = gaiaMaterialDocService.getBatchSaleList(time);
        log.info("{}批发销售数据 供应商测试数据待同步数据一共{}", time, diboBoOriginals.size());
        if (CollectionUtils.isEmpty(diboBoOriginals)) {
            return;
        }
        List<WholesaleSalesRecord> collect = diboBoOriginals.stream().filter(r -> r.getMatQty() != 0).map(r -> {
            String wmPch = r.getMatBatch();
            String wmSpBm = r.getMatProCode();
//            String matId = r.getMatPoId();
//            String matPoLineno = r.getMatPoLineno();
            String matType = r.getMatType();
//            String outId = matId + "|" + matPoLineno;
            List<WholesaleSalesRecord> list = wholesaleSalesRecordService.list(Wrappers.<WholesaleSalesRecord>lambdaQuery()
//                    .eq(WholesaleSalesRecord::getOutId, outId)
                    .eq(WholesaleSalesRecord::getBatchNo, wmPch).eq(WholesaleSalesRecord::getProCode, wmSpBm));

            if (CollectionUtils.isNotEmpty(list) && list.size() > 1) {
                log.error("同步数据失败，存在多条数据,list={}", JSON.toJSONString(list));
            }
            WholesaleSalesRecord wholesaleSalesRecord = list.stream().findFirst().orElse(null);
            Double matQty = r.getMatQty();
            int totalNum = matQty.intValue();
            //退货是-的


            if (Objects.nonNull(wholesaleSalesRecord)) {
                wholesaleSalesRecord.setTotalNum(totalNum);
            } else {
                wholesaleSalesRecord = new WholesaleSalesRecord();
                //随机天数时间
                LocalDateTime localDateTime = LocalDateTime.of(LocalDate.now().plusDays(RandomUtil.randomInt(3, 4)), LocalTime.of(0, 0, 0));

                LocalDateTime with = localDateTime.with(TemporalAdjusters.lastDayOfMonth());
                //大于月末的时间取月末
                if (localDateTime.isBefore(with)) {
                    long epochMilli = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
                    wholesaleSalesRecord.setEndTime(epochMilli);
                } else {
                    long epochMilli = with.toInstant(ZoneOffset.of("+8")).toEpochMilli();
                    wholesaleSalesRecord.setEndTime(epochMilli);
                }

                long epochMilli = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
                wholesaleSalesRecord.setUsedNum(0);
                wholesaleSalesRecord.setProCode(wmSpBm);
                wholesaleSalesRecord.setEndTime(epochMilli);
                wholesaleSalesRecord.setBatchNo(r.getMatBatch());
                wholesaleSalesRecord.setTotalNum(totalNum);
            }
            return wholesaleSalesRecord;
        }).collect(Collectors.toList());
        log.info("[生成测试数据]开始插入，耗时={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        log.info("批发数据保存，collect={}", JSON.toJSONString(collect));
        wholesaleSalesRecordService.saveOrUpdateBatch(collect);
        log.info("[生成测试数据]插入完成，耗时={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        //先计算退货
        testBizService.generateSingleTestDataReturn(time);
        log.info("[生成测试数据]退货完成，耗时={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));

        //再计算测试数据
        testBizService.generateSingleTestData(time);
        log.info("[生成测试数据]测试数据生成完成，耗时={}", stopwatch.elapsed(TimeUnit.MILLISECONDS));
        stopwatch.stop();

    }

    public void syncBatch(String time) {


    }
}
